package com.zz.parkingsystem.aop;


import com.alibaba.fastjson.JSON;
import com.zz.parkingsystem.entity.Admin;
import com.zz.parkingsystem.entity.SystemRunning;
import com.zz.parkingsystem.service.SystemRunningService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @author wangyuxiang
 * 切面，定义通知和切点之间关系
 * @@@@@@@加注解之前先登录获取session,不然没有session会报空指针异常
 */
@Component
@Aspect
@Slf4j
public class LogAspect2 {

    /**
     * 用于记录日志到数据库
     */
    @Resource
    private SystemRunningService systemRunningService;

    /**
     * 将注解定义为切点
     */
    @Pointcut("@annotation(com.zz.parkingsystem.aop.LogAnnotation)")
    public void pt() {
    }

    /**
     * 用环绕通知，方法前后进行增强
     */
    @Around("pt()")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {

        //开始时间
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = joinPoint.proceed();
        //执行时长
        long time = System.currentTimeMillis() - beginTime;
        //保存日志
        recordLog(joinPoint, beginTime);
        return result;

    }

    /**
     * 记录日志具体方法
     *
     * @param joinPoint
     */
    private void recordLog(ProceedingJoinPoint joinPoint, long time) {
        //通过反射创建注解
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
        log.info("=====================log start==============================");
        log.info("module:{}", logAnnotation.module());
        log.info("operation:{}", logAnnotation.operation());

        //请求方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        log.info("request method:{}", className + "." + methodName + "()");

        //请求参数
        Object[] args = joinPoint.getArgs();
        //alibaba工具转换json参数格式,方便观看
        if (args.length != 0) {
            String params = JSON.toJSONString(args[0]);
            log.info("params:{}", args[0]);
        } else {
            log.info("params:{}", "无参数");
        }


        //获取request 设置ip地址
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String ip = request.getRemoteAddr();

        log.info("ip:{}", ip);
        log.info("=====================log end==============================");

        //获取到session人员信息
//        Admin admin = (Admin) request.getSession(true).getAttribute("admin");
//        String adminNickname = admin.getAdminNickname();

        //className:请求module methodName:操作方法 IP 请求ip地址
        //操作者：adminNickname
        SystemRunning systemRunning = new SystemRunning();
        systemRunning.setSrClassName(logAnnotation.module());
        systemRunning.setSrMethodName(logAnnotation.operation());
//        systemRunning.setSrOperator(admin.getAdminNickname());
        systemRunning.setSrOperator("某某管理员");
        systemRunning.setSrOperateTime(new Date(time));
        systemRunningService.insertSelective(systemRunning);
    }


}
